package com.hjb.service.impl.withdraw;

import com.hjb.service.domain.siteuser.SiteUser;
import com.hjb.service.domain.siteuser.SiteUserExample;
import com.hjb.service.domain.siteuseraccount.SiteUserAccount;
import com.hjb.service.domain.siteuseraccount.SiteUserAccountExample;
import com.hjb.service.domain.siteuseraccount.SiteUserBankcard;
import com.hjb.service.domain.withdraw.PayCashWithdraw;
import com.hjb.service.domain.withdraw.PayCashWithdrawExample;
import com.hjb.service.gateway.baofoo.BaoFooPayService;
import com.hjb.service.gateway.baofoo.domain.TransHead;
import com.hjb.service.gateway.baofoo.domain.request.TransReqBF0040001;
import com.hjb.service.gateway.baofoo.domain.request.TransReqBF0040002;
import com.hjb.service.gateway.baofoo.domain.response.TransRespBF0040001;
import com.hjb.service.gateway.baofoo.domain.response.TransRespBF0040002;
import com.hjb.service.gateway.baofoo.domain.response.TransRespBF40001Async;
import com.hjb.service.mapper.PayCashWithdrawMapper;
import com.hjb.service.mapper.SiteUserAccountMapper;
import com.hjb.service.mapper.SiteUserBankcardMapper;
import com.hjb.service.mapper.SiteUserMapper;
import com.hjb.service.utils.DateUtil;
import com.hjb.service.utils.MapUtil;
import com.hjb.service.withdraw.WithDrawService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by gy on 2017/7/28.
 * 提现接口实现
 */
@Service
public class WithDrawServiceImpl implements WithDrawService {

	private Logger log = LoggerFactory.getLogger(getClass());

	@Autowired
	private BaoFooPayService baoFooPayService;
	@Autowired
	private SiteUserMapper siteUserMapper;
	@Autowired
	private PayCashWithdrawMapper payCashWithdrawMapper;
	@Autowired
	private SiteUserBankcardMapper siteUserBankcardMapper;
	@Autowired
	private SiteUserAccountMapper siteUserAccountMapper;

	@Override
	public Map<String, Object> withdraw(PayCashWithdraw payCashWithdraw) {
		Map<String, Object> resMap = new HashMap<String, Object>();
		try {
			if (payCashWithdraw.getAmount() == null){
				resMap.put("result_code",MapUtil.INTF_ERR_CODE);
				resMap.put("result_info", "提现金额为空");
				return resMap;
			}
			if (new BigDecimal(0).compareTo(payCashWithdraw.getAmount()) !=-1){//充值金额大于0
				resMap.put("result_code",MapUtil.INTF_ERR_CODE);
				resMap.put("result_info", "提现金额有误");
				return resMap;
			}
			//查询用户信息
			SiteUser siteUser = new SiteUser();
			SiteUserExample siteUserExample = new SiteUserExample();
			siteUserExample.createCriteria().andUserIdEqualTo(payCashWithdraw.getUserId());
			List<SiteUser> siteUserList = siteUserMapper.selectByExample(siteUserExample);
			if (siteUserList == null || siteUserList.size() == 0){
				resMap.put("result_code", MapUtil.INTF_ERR_CODE);
				resMap.put("result_info", "无用户信息");
				return resMap;
			}
			//查询用户绑卡信息
			SiteUserBankcard siteUserBankcard = new SiteUserBankcard();
			SiteUserBankcard record = new SiteUserBankcard();
			record.setUserId(payCashWithdraw.getUserId());
			record.setStatus(1);
			record.setUnbindStatus(0);
			record.setCardType(2);
			List<SiteUserBankcard> userBankcards = siteUserBankcardMapper.selectByExample(record);
			if (userBankcards == null || userBankcards.size() == 0){
				resMap.put("result_code", MapUtil.INTF_ERR_CODE);
				resMap.put("result_info", "无用户绑卡信息");
				return resMap;
			}
			//查询用户账户信息
			SiteUserAccountExample userAccountExample = new SiteUserAccountExample();
			userAccountExample.createCriteria().andUserIdEqualTo(payCashWithdraw.getUserId());
			List<SiteUserAccount> userAccountList =  siteUserAccountMapper.selectByExample(userAccountExample);
			if (userAccountList == null || userAccountList.size() == 0){//无用户账户记录
				log.info("未查到用户账户记录，userId："+payCashWithdraw.getUserId());
				resMap.put("result_code", MapUtil.INTF_ERR_CODE);
				resMap.put("result_info", "无用户账户信息");
				return resMap;
			}
			SiteUserAccount siteUserAccount = userAccountList.get(0);
			BigDecimal divide = siteUserAccount.getFrozenAccount().divide(payCashWithdraw.getAmount());

			if (new BigDecimal(0).compareTo(divide) !=-1){
				resMap.put("result_code",MapUtil.INTF_ERR_CODE);
				resMap.put("result_info", "提现金额小于账户冻结金额");
				return resMap;
			}
			siteUser = siteUserList.get(0);
			siteUserBankcard = userBankcards.get(0);
			//调取三方提现
			TransReqBF0040001 transReqBF0040001 = getWithdrawParam(payCashWithdraw,siteUser,siteUserBankcard);
			Map<String, Object> dataMap = baoFooPayService.proxyPay(transReqBF0040001);
			//业务处理
			if (dataMap == null){
				resMap.put("result_code", MapUtil.INTF_ERR_CODE);
				resMap.put("result_info", "提现失败");
				return resMap;
			}
			resMap.put("result_code", MapUtil.INTF_ERR_CODE);
			TransHead transHead = (TransHead)dataMap.get("info");
			if ("0000".equals(transHead.getReturn_code())){
				List<TransRespBF0040001> datas = (List<TransRespBF0040001>)dataMap.get("data");
				if (datas == null || datas.size() == 0){
					resMap.put("result_code", MapUtil.INTF_ERR_CODE);
					resMap.put("result_info", "提现失败");
					return resMap;
				}
				TransRespBF0040001 transRespBF0040001 = datas.get(0);
				//更新提现记录信息 设置状态为充值中
				payCashWithdraw = getWithdraw(payCashWithdraw,siteUserBankcard.getCardNo());

				payCashWithdraw.setBatchId(transRespBF0040001.getTrans_batchid());
				payCashWithdraw.setTradeNo(transRespBF0040001.getTrans_orderid());
				payCashWithdraw.setRetCode(transHead.getReturn_code());
				payCashWithdraw.setMsg(transHead.getReturn_msg());
				payCashWithdraw.setCallbackMsg(transRespBF0040001.toString());
				payCashWithdrawMapper.updateByPrimaryKey(payCashWithdraw);
				resMap.put("result_code", MapUtil.INTF_SUC_CODE);
			}
			resMap.put("result_info", transHead.getReturn_msg());

		}catch (Exception e){
			log.info("提现失败"+e);
			resMap.put("result_code",MapUtil.INTF_ERR_CODE);
			resMap.put("result_info", "请求失败");
		}
		return resMap;
	}

//	@Override
//	public String withdrawNotify(String param) {
//		String result = null;
//		List<TransRespBF40001Async> notifyDatas = baoFooPayService.proxyPayNotify(param);
//		if (notifyDatas != null && notifyDatas.size() > 0){
//			TransRespBF40001Async transRespBF40001Async = notifyDatas.get(0);
//			//业务处理充值信息和用户账户
//			if (transRespBF40001Async != null){
//				result = dealWithDraw(transRespBF40001Async,null);
//			}
//		}
//		return result;
//	}

//	@Override
//	public void withdrawQuery(TransReqBF0040002 transReqBF0040002) {
//		if (transReqBF0040002 != null){
//			Map<String, Object> resultMap = baoFooPayService.proxyPayQuery(transReqBF0040002);
//			TransHead transHead = (TransHead)resultMap.get("info");
//			transHead.setReturn_code("0000");
//			transHead.setReturn_msg("0000");
//			if ("0000".equals(transHead.getReturn_code())){
//				List<TransRespBF0040002> datas = (List<TransRespBF0040002>)resultMap.get("data");
//				if (datas == null || datas.size() == 0){
//					log.info("三方返回数据为空");
//					return;
//				}
//				TransRespBF0040002 transRespBF0040002 = datas.get(0);
//				/*TransRespBF0040002 transRespBF0040002 = new TransRespBF0040002();
//				transRespBF0040002.setTrans_no(transReqBF0040002.getTrans_no());
//				transRespBF0040002.setTrans_money("10");
//				transRespBF0040002.setTrans_starttime("2017-07-29 18:53:12");
//				transRespBF0040002.setState("1");*/
//				dealWithDraw(transRespBF0040002,transHead);
//			}
//		}
//	}

	private PayCashWithdraw getWithdraw(PayCashWithdraw payCashWithdraw,String cardNo){
		payCashWithdraw.setSendTime(new Date());
		payCashWithdraw.setStatus(2);
		payCashWithdraw.setCardNo(cardNo);
		payCashWithdraw.setPayType(1);
		return payCashWithdraw;
	}
	private TransReqBF0040001 getWithdrawParam(PayCashWithdraw payCashWithdraw,SiteUser siteUser,SiteUserBankcard siteUserBankcard){
		TransReqBF0040001 transReqBF0040001 = new TransReqBF0040001();
		transReqBF0040001.setTrans_no(payCashWithdraw.getOrderId());
		transReqBF0040001.setTrans_money(String.valueOf(payCashWithdraw.getAmount()));
		transReqBF0040001.setTo_acc_name(siteUser.getName());
		transReqBF0040001.setTo_acc_no(siteUser.getBankCardNo());
		transReqBF0040001.setTo_bank_name(siteUser.getBankName());
		transReqBF0040001.setTo_pro_name(siteUserBankcard.getProviceCode());
		transReqBF0040001.setTo_city_name(siteUserBankcard.getCityCode());
		transReqBF0040001.setTo_acc_dept(siteUserBankcard.getBankAddr());
		transReqBF0040001.setTrans_summary("");
		transReqBF0040001.setTrans_card_id(siteUser.getCardNumber());
		transReqBF0040001.setTrans_mobile(siteUser.getBankPhone());

		/*transReqBF0040001.setTo_acc_name("王宝");
		transReqBF0040001.setTo_acc_no("6228480444455553333");
		transReqBF0040001.setTo_bank_name("中国农业银行");
		transReqBF0040001.setTo_pro_name("上海市");
		transReqBF0040001.setTo_city_name("上海市");
		transReqBF0040001.setTo_acc_dept("支行");
		transReqBF0040001.setTrans_summary("备注1");
		transReqBF0040001.setTrans_card_id("320301198502169142");
		transReqBF0040001.setTrans_mobile("15831783630");*/
		return transReqBF0040001;
	}
	//处理体现业务
	private String dealWithDraw(Object object,TransHead transHead){
		try {
			String orderNo = null;//订单号
			String message = null;//三方返回信息
			String errorInfo = null;//错误信息信息
			String status = null;//三方返回状态
			String dealTime = null;//三方处理时间
			BigDecimal amount =null;//交易金额
			BigDecimal fee =null;//交易手续费

			if (object.getClass().getTypeName().contains("TransRespBF0040002")){//查询
				TransRespBF0040002 transRespBF0040002 = (TransRespBF0040002)object;
				orderNo = transRespBF0040002.getTrans_no();
				amount = new BigDecimal(transRespBF0040002.getTrans_money());
				message = transRespBF0040002.toString();
				status = transRespBF0040002.getState();
				dealTime = transRespBF0040002.getTrans_endtime();
				fee = new BigDecimal(transRespBF0040002.getTrans_fee());
			}
			if (object.getClass().getTypeName().contains("TransRespBF40001Async")){//通知
				TransRespBF40001Async transRespBF40001Async = (TransRespBF40001Async)object;
				orderNo = transRespBF40001Async.getTrans_no();
				amount = new BigDecimal(transRespBF40001Async.getTrans_money());
				message = transRespBF40001Async.toString();
				status = transRespBF40001Async.getState();
				dealTime = transRespBF40001Async.getTrans_endtime();
				fee = new BigDecimal(transRespBF40001Async.getTrans_fee());
			}
			if ("0".equals(status)){
				log.info("三方返回状态为处理中，不需处理业务");
				return null;
			}
			//1.获取充值记录
			PayCashWithdrawExample example = new PayCashWithdrawExample();
			example.createCriteria().andOrderIdEqualTo(orderNo).andAmountEqualTo(amount).andStatusEqualTo(2);
			List<PayCashWithdraw> payCashWithdrawList = payCashWithdrawMapper.selectByExample(example);
			if (payCashWithdrawList == null || payCashWithdrawList.size() ==0){
				log.info("未查到等待回调的提现记录，订单号："+orderNo +"提现金额："+amount);
				return null;
			}
			//2.判断是否处理提现记录 提现金额=用户账户表中体现冻结金额
			PayCashWithdraw payCashWithdraw = payCashWithdrawList.get(0);
			//查询用户账户信息
			SiteUserAccountExample userAccountExample = new SiteUserAccountExample();
			userAccountExample.createCriteria().andUserIdEqualTo(payCashWithdraw.getUserId());
			List<SiteUserAccount> userAccountList =  siteUserAccountMapper.selectByExample(userAccountExample);
			if (userAccountList == null || userAccountList.size() == 0){//无用户账户记录
				log.info("未查到用户账户记录，userId："+payCashWithdraw.getUserId());
				return null;
			}

			SiteUserAccount siteUserAccount = userAccountList.get(0);
			BigDecimal frozenAmount = siteUserAccount.getFrozenAccount();//提现冻结金额
			if (amount.equals(frozenAmount)){
				//3.更新充值记录状态
				switch (status){//成功
					case "1":
						payCashWithdraw.setStatus(1);
						break;
					case "-1"://失败
						payCashWithdraw.setStatus(3);
						break;
				}
				payCashWithdraw.setReplyTime(DateUtil.parse(dealTime,"yyyy-MM-dd HH:mm:ss"));
				payCashWithdraw.setCallbackMsg(message);
				payCashWithdraw.setPayFee(fee);
				payCashWithdraw.setMsg(errorInfo);
				if (transHead != null){
					payCashWithdraw.setRetCode(transHead.getReturn_code());
				}

				payCashWithdrawMapper.updateByExampleSelective(payCashWithdraw,example);
				// 4.判断是否提现成功 成功更新用户账户表
				if (1 == payCashWithdraw.getStatus()){
					siteUserAccount.setFrozenAccount(frozenAmount.divide(amount));
					SiteUserAccountExample accountExample = new SiteUserAccountExample();
					accountExample.createCriteria().andUserIdEqualTo(payCashWithdraw.getUserId()).andFrozenAccountEqualTo(amount);
					siteUserAccountMapper.updateAccountExample(siteUserAccount,accountExample);
				}
			}else {
				log.info("金额不匹配---冻结提现金额："+frozenAmount +"提现金额："+amount);
				return null;
			}
		}catch (Exception e){
			log.info("处理提现业务逻辑失败");
			return null;
		}
		return "OK";
	}
}
